package com.itheima.reggie.service.impl;

import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.itheima.reggie.common.R;
import com.itheima.reggie.common.dto.SaveMealDto;
import com.itheima.reggie.common.dto.SetmealDishFrontDto;
import com.itheima.reggie.common.dto.SetmealListDto;
import com.itheima.reggie.entity.Category;
import com.itheima.reggie.entity.Dish;
import com.itheima.reggie.entity.Setmeal;
import com.itheima.reggie.entity.SetmealDish;
import com.itheima.reggie.mapper.CategoryMapper;
import com.itheima.reggie.mapper.SetmealMapper;
import com.itheima.reggie.service.CategoryService;
import com.itheima.reggie.service.DishService;
import com.itheima.reggie.service.SetmealDishService;
import com.itheima.reggie.service.SetmealService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.ObjectUtils;

import java.util.ArrayList;
import java.util.List;
import java.util.function.Function;
import java.util.stream.Collectors;

@Service
@Slf4j
public class SetmealServiceImpl extends ServiceImpl<SetmealMapper, Setmeal> implements SetmealService {

    @Autowired
    CategoryService categoryService;

    @Autowired
    CategoryMapper categoryMapper;

    @Autowired
    SetmealDishService setmealDishService;

    @Autowired
    DishService dishService;

    @Override
    public Integer selectByCategoryId(Long id) {
        LambdaQueryWrapper<Setmeal> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Setmeal::getCategoryId, id);
        List<Setmeal> list = this.list(wrapper);
        return list.size();
    }


    @Override
    public R<String> add(SaveMealDto saveMealDto) {
        Setmeal setmeal = new Setmeal();
        BeanUtils.copyProperties(saveMealDto, setmeal);
        this.save(setmeal);

        Long id = setmeal.getId();

        List<SetmealDish> setmealDishes = saveMealDto.getSetmealDishes();
        ArrayList<SetmealDish> setmealDishes1 = new ArrayList<>();
        for (SetmealDish setmealDish : setmealDishes) {
            setmealDish.setSetmealId(id);
            setmealDishes1.add(setmealDish);
        }

        setmealDishService.saveBatch(setmealDishes1);
        return R.success("添加成功！");

    }


    @Override
    public R<Page<SetmealListDto>> pageBySetmeal(Long page, Long pageSize, String name) {
        if (ObjectUtils.isEmpty(page)
                || page <= 0) {
            page = 1L;
        }
        if (ObjectUtils.isEmpty(pageSize)
                || pageSize <= 0) {
            page = 10L;
        }


        Page<Setmeal> pageParam = new Page<>(page, pageSize);
        LambdaQueryWrapper<Setmeal> wrapper = new LambdaQueryWrapper<>();
        wrapper.like(!ObjectUtils.isEmpty(name), Setmeal::getName, name);
        Page<Setmeal> page1 = this.page(pageParam, wrapper);
        List<Setmeal> records = page1.getRecords();
        ArrayList<SetmealListDto> setmealListDtos = new ArrayList<>();
        for (Setmeal record : records) {
            SetmealListDto setmealListDto = new SetmealListDto();
            Long categoryId = record.getCategoryId();
            Category byId = categoryService.getById(categoryId);
            BeanUtils.copyProperties(record, setmealListDto);
            setmealListDto.setCategoryName(byId.getName());
            setmealListDtos.add(setmealListDto);
        }

        Page<SetmealListDto> dtoPage = new Page<>();
        BeanUtils.copyProperties(page1, dtoPage);
        dtoPage.setRecords(setmealListDtos);
        return R.success(dtoPage);

    }

    @Override
    public R<String> deleteById(List<Long> ids) {
        if (ObjectUtils.isEmpty(ids)) {
            return R.error("参数错误！");
        }
        LambdaQueryWrapper<SetmealDish> wrapper = new LambdaQueryWrapper<>();
        wrapper.in(SetmealDish::getSetmealId, ids);
        //List<SetmealDish> list = setmealDishService.list(wrapper);
        //List<Long> list1 = list.stream().map(setmealDish -> setmealDish.getId()).collect(Collectors.toList());
        //setmealDishService.removeByIds(wrapper);
        setmealDishService.remove(wrapper);
        this.removeByIds(ids);
        return R.success("删除成功！");
    }

    @Override
    public R<SaveMealDto> findByIdSetmeal(Long id) {
        if (ObjectUtils.isEmpty(id)) {
            return R.error("参数错误！");
        }
        Setmeal dbSetmeal = this.getById(id);
        LambdaQueryWrapper<SetmealDish> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(SetmealDish::getSetmealId, id);
        List<SetmealDish> setmealDishes = setmealDishService.list(wrapper);
        SaveMealDto saveMealDto = new SaveMealDto();
        BeanUtils.copyProperties(dbSetmeal, saveMealDto);
        saveMealDto.setSetmealDishes(setmealDishes);
        return R.success(saveMealDto);
    }

    @Override
    public R<String> updateSetmeal(SaveMealDto saveMealDto) {
        System.out.println(saveMealDto);
        Setmeal setmeal = new Setmeal();
        BeanUtils.copyProperties(saveMealDto, setmeal);
        this.saveOrUpdate(setmeal);
        Long id = setmeal.getId();

        LambdaQueryWrapper<SetmealDish> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(SetmealDish::getSetmealId, saveMealDto.getId());
        setmealDishService.remove(wrapper);

        List<SetmealDish> setmealDishes = saveMealDto.getSetmealDishes();
        setmealDishes = setmealDishes.stream().map(setmealDish -> {
            setmealDish.setSetmealId(id);
            return setmealDish;
        }).collect(Collectors.toList());

        setmealDishService.saveOrUpdateBatch(setmealDishes);

        return R.success("成功!");
    }

    @Override
    public R<String> stopSell(List<Long> ids) {
        if (ObjectUtils.isEmpty(ids)) {
            return R.error("参数非法！");
        }
        ArrayList<Setmeal> dishes = new ArrayList<>();
        for (Long id : ids) {
            Setmeal setmeal = new Setmeal();
            setmeal.setId(id);
            setmeal.setStatus(0);
            dishes.add(setmeal);
        }

        this.updateBatchById(dishes);
        return R.success("停售成功！");
    }

    /**
     * 启售套餐需要判断菜品是否处于在售状态
     *
     * @return
     * @param启售套餐的ids
     */
    @Override
    public R<String> startSell(List<Long> ids) {
        if (ObjectUtils.isEmpty(ids)) {
            return R.error("参数非法！");
        }
        //想要启售，需要看其包含的所有菜品是否为在售状态
        //通过想要启售的套餐Id查询套餐下所包含的菜品Ids
        LambdaQueryWrapper<SetmealDish> wrapper = new LambdaQueryWrapper<>();
        wrapper.in(SetmealDish::getSetmealId, ids);
        List<SetmealDish> setmealDishList = setmealDishService.list(wrapper);
        List<Long> dishIds = setmealDishList.stream().map(SetmealDish::getDishId).collect(Collectors.toList());
        //通过菜品Ids查询菜品的在售状态
        LambdaQueryWrapper<Dish> wrapper1 = new LambdaQueryWrapper<>();
        wrapper1.in(Dish::getId, dishIds);
        List<Dish> dishList = dishService.list(wrapper1);
        //求出菜品状态码的和（弃用）
        //Integer collect = dishList.stream().collect(Collectors.summingInt(Dish::getStatus));
        ArrayList<Long> longs = new ArrayList<>();
        for (Dish dish : dishList) {
            if (dish.getStatus() == 0) {
                longs.add(dish.getId());
            }
        }
        if (longs.size() == 0) {
            ArrayList<Setmeal> dishes = new ArrayList<>();
            for (Long id : ids) {
                Setmeal setmeal = new Setmeal();
                setmeal.setId(id);
                setmeal.setStatus(1);
                dishes.add(setmeal);
            }

            this.updateBatchById(dishes);
            return R.success("启售成功！");
        }
        LambdaQueryWrapper<SetmealDish> wrapper2 = new LambdaQueryWrapper<>();
        wrapper2.in(SetmealDish::getDishId, longs);
        List<SetmealDish> list = setmealDishService.list(wrapper2);
        //判断在售菜品状态码的和与套餐内所包含的菜品数量是否相等，相等说明全部菜品均处于在售状态（弃用）
        /*if (dishList.size() != collect) {
            return R.error("套餐内有菜品处于禁售状态！");
        }*/
        //

        List<Long> setmealDish = list.stream().map(SetmealDish::getSetmealId).collect(Collectors.toList());
        ids.removeAll(setmealDish);
        if (ids.size() == 0) {
            return R.error("选中的启售套餐内包含停售的菜品！");
        }
        ArrayList<Setmeal> dishes = new ArrayList<>();
        for (Long id : ids) {
            Setmeal setmeal = new Setmeal();
            setmeal.setId(id);
            setmeal.setStatus(1);
            dishes.add(setmeal);
        }

        this.updateBatchById(dishes);
        return R.success("启售成功！");
    }

    /**
     * 通过套餐分类Id查询此套餐下包含哪些套餐
     *
     * @return
     * @param套餐分类的Id
     * @param套餐的启售停售状态码
     */
    @Override
    public R<List<Setmeal>> getSetmealList(Long categoryId, Integer status) {

        LambdaQueryWrapper<Setmeal> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Setmeal::getCategoryId, categoryId);
        wrapper.eq(Setmeal::getStatus, status);
        List<Setmeal> setmealList = this.list(wrapper);
        return R.success(setmealList);
    }

    /**
     * 通过套餐Id查询套餐下有哪些菜品
     *
     * @return
     * @param套餐的Id
     */
    @Override
    public R<List<Dish>> getSetmealDishList(Long id) {
        LambdaQueryWrapper<SetmealDish> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(SetmealDish::getSetmealId, id);
        List<SetmealDish> list = setmealDishService.list(wrapper);
        List<Long> dishIds = list.stream().map(SetmealDish::getDishId).collect(Collectors.toList());
        LambdaQueryWrapper<Dish> wrapper1 = new LambdaQueryWrapper<>();
        wrapper1.in(Dish::getId, dishIds);
        List<Dish> list1 = dishService.list(wrapper1);
        return R.success(list1);
    }


}